package main

import (
	"encoding/hex"
	"fmt"
	"log"
	"time"
)

// 定义协议中的一些常量
const (
	SOI      = 0x7E  // Start of Information
	EOI      = 0x0D  // End of Information
	VER      = 0x21  // Protocol version
	ADR      = 0x01  // Default address
	CID1     = 0x60  // 设备类型: 分散空调
	CID2     = 0x85  // 获取机组运行模式报警状态命令
	LENID    = 0     // 数据长度标识
)

// 计算校验和 (CHKSUM)
func calculateChecksum(data []byte) uint16 {
	var sum uint16
	for _, b := range data {
		sum += uint16(b)
	}
	// 计算校验和: 校验和 = 65536 - (和的低16位)
	return ^sum + 1
}

// 创建命令帧
func createCommand() []byte {
	// 创建命令帧结构
	command := []byte{
		byte(SOI),   // SOI
		byte(VER),   // VER
		byte(ADR),   // ADR
		byte(CID1),  // CID1
		byte(CID2),  // CID2
		byte(LENID), // LENGTH (LENID = 0)
		0x00, 0x00,  // CHKSUM (初始化，稍后计算)
		byte(EOI),   // EOI
	}

	// 计算并添加校验和
	chksum := calculateChecksum(command[1:len(command)-3]) // 校验和不包括SOI和EOI
	command[6] = byte(chksum >> 8)  // 高字节
	command[7] = byte(chksum & 0xFF) // 低字节

	return command
}

// 解析响应数据
func parseResponse(response []byte) {
	if len(response) < 12 {
		log.Println("响应数据格式错误")
		return
	}

	// 解析响应中的报警状态数据
	data := response[8 : 8+19] // 报警状态字段长度为19字节

	// 解析各个报警状态
	for i, alarmByte := range data {
		for j := 0; j < 8; j++ {
			if alarmByte&(1<<j) != 0 {
				fmt.Printf("报警状态 %d: 位 %d 激活\n", i+1, j)
			}
		}
	}
}

func main() {
	// 创建并打印命令帧
	command := createCommand()
	fmt.Printf("发送的命令帧: %s\n", hex.EncodeToString(command))

	// 假设我们通过网络发送并接收到响应数据
	// 以下为模拟的响应数据
	response := []byte{
		0x7E, 0x21, 0x01, 0x60, 0x85, 0x00, 0x38, 0x02, 0x00, 0x00, 0x38, 0x39, 0x00, 0x01, 0x0D,
	}
	// 解析响应数据
	parseResponse(response)

	// 模拟等待一段时间，再次发送命令（如果需要）
	time.Sleep(1 * time.Second)
}
